/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Vue;

import com.trolltech.qt.core.QPointF;
import com.trolltech.qt.core.QTimer;
import com.trolltech.qt.gui.QColor;
import com.trolltech.qt.gui.QGraphicsItem;
import com.trolltech.qt.gui.QGraphicsItemInterface;
import com.trolltech.qt.gui.QLineF;
import com.trolltech.qt.gui.QPolygonF;
import java.util.List;
import java.util.Random;
import Entites.Espece;

/**
 *
 * @author JeanW
 */
abstract class PEspece extends QGraphicsItem {

    int i = 0;
    protected Espece uneEspece;
    double angle = 0;
    double speed = 0;
    boolean status = false;
    QColor color = null;
    Random generator = new Random();
    private Signal0 stop = new Signal0();
    public Signal1<Espece> mort = new Signal1<>();
    public Signal0 moveSign = new Signal0();
    public Signal0 collision = new Signal0();
    private Signal0 start = new Signal0();
    private QTimer timer = new QTimer();
    static final double TWO_PI = Math.PI * 2;
    private QPolygonF polygon = new QPolygonF();
    private QPointF origo = new QPointF(0, 0);

    public PEspece(Espece uneEspece) {
        super();
        this.uneEspece = uneEspece;

        rotate(generator.nextDouble() * 360);

        timer.start(1000 / 33);
        QTimer timer = new QTimer();
        timer.start(1000 / 33);
        timer.timeout.connect(this, "move()");
        start.connect(timer, "start()");
        stop.connect(timer, "stop()");
    }

    public void move() {
        // limite du déplacement
        QLineF lineToCenter = new QLineF(origo,
                mapFromScene(500, 500));
        if (lineToCenter.length() > 150) {
            double angleToCenter = Math.acos(lineToCenter.dx()
                    / lineToCenter.length());
            if (lineToCenter.dy() < 0) {
                angleToCenter = TWO_PI - angleToCenter;
            }
            angleToCenter = normalizeAngle((Math.PI - angleToCenter)
                    + Math.PI / 2);

            if (angleToCenter < Math.PI && angleToCenter > Math.PI / 4) {
                // tourne à gauche
                angle += (angle < -Math.PI / 2) ? 0.25 : -0.25;
            } else if (angleToCenter >= Math.PI
                    && angleToCenter < (Math.PI + Math.PI / 2
                    + Math.PI / 4)) {
                // tourne à droite
                angle += (angle < Math.PI / 2) ? 0.25 : -0.25;
            }
        } else if (Math.sin(angle) < 0) {
            angle += 0.25;
        } else if (Math.sin(angle) > 0) {
            angle -= 0.25;
        }


        // Gestion de la collision

        polygon.clear();
        polygon.append(mapToScene(0, 0));
        polygon.append(mapToScene(-1, -1));
        polygon.append(mapToScene(1, -1));

        List<QGraphicsItemInterface> listPE = scene().items(polygon);
        for (QGraphicsItemInterface item : listPE) {
            if (item == this) {
                continue;
            }

            QLineF lineToPE = new QLineF(origo,
                    mapFromItem(item, 0, 0));
            double angleToPE = Math.acos(lineToPE.dx()
                    / lineToPE.length());
            if (lineToPE.dy() < 0) {
                i++;
                //System.out.println("Collision " + i);
                moveSign.emit();
                status = true;
                collision.emit();

                angleToPE = TWO_PI - angleToPE;
            }
            angleToPE = normalizeAngle((Math.PI - angleToPE)
                    + Math.PI / 2);

            if (angleToPE >= 0 && angleToPE < (Math.PI / 2)) {
                // tourne à droite
                angle += 0.5;
            } else if (angleToPE <= TWO_PI
                    && angleToPE > (TWO_PI - Math.PI / 2)) {
                // tourne à gauche
                angle -= 0.5;
            }
        }

        // mouvement aléatoire
        if (listPE.size() < 1 && generator.nextDouble() < 0.1) {
            if (generator.nextDouble() > 0.5) {
                angle += generator.nextDouble() / 5;
            } else {
                angle -= generator.nextDouble() / 5;
            }
        }

        speed += (-50 + generator.nextDouble() * 100) / 100.0;

        double dx = Math.sin(angle) * 10;

        rotate(dx);
        setPos(mapToParent(0, -(3 + Math.sin(speed) * 3)));

        // Durée de vie
        uneEspece.veillirEspece();

        if (i == 1000) {
            mort.emit(uneEspece);
            i = 0;
        }

        if (uneEspece.getDureeVie() == 0) {
            System.out.println("Mort de " + uneEspece.getUnEsprit().getNom());
            this.dispose();
        }

    }

    private double normalizeAngle(double angle) {
        while (angle < 0) {
            angle += TWO_PI;
        }
        while (angle > TWO_PI) {
            angle -= TWO_PI;
        }
        return angle;
    }
}
